package bb.lanxing.activity.bluetooth;

import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.github.mikephil.charting.utils.Utils;

import org.json.JSONObject;

import java.text.DecimalFormat;

import bb.lanxing.App;
import bb.lanxing.R;
import bb.lanxing.activity.base.BaseDisplayActivity;
import bb.lanxing.calc.data.DisplayPoint;
import bb.lanxing.devices.utils.XZDeviceHelper;
import bb.lanxing.lib.devices.api.ConnectionListener;
import bb.lanxing.lib.devices.api.DeviceManager;
import bb.lanxing.lib.devices.api.SmartDevice;
import bb.lanxing.lib.devices.base.DeviceContext;
import bb.lanxing.lib.devices.ble.BleCons;
import bb.lanxing.manager.RemoteSharedPreference;
import bb.lanxing.manager.SPConstant;
import bb.lanxing.model.database.Device;
import bb.lanxing.network.BiCiCallback;
import bb.lanxing.network.MyHttpClient;
//import bb.lanxing.util.Log;
import bb.lanxing.view.BiciAlertDialogBuilder;
import gov.nist.core.Separators;
import kotlinx.coroutines.DebugKt;

public class CadenceStatusActivity extends BaseDisplayActivity implements ConnectionListener {
    final private static String TAG = "CadenceStatusActivity";
    private TextView altitudeView;
    private TextView batteryView;
    private TextView cadenceView;
    private Device device;
    private TextView nameView;
    private LinearLayout pressureLayout;
    private TextView pressureView;
    private TextView speedView;
    private TextView temperatureView;
    private TextView unbindBtn;
    private TextView wheelLengthView;
    private RelativeLayout wheelSettingView;
    private RelativeLayout deviceSpeed;
    private RelativeLayout deviceCandence;
    private final DecimalFormat decimalFormat = new DecimalFormat("0.00");
    private final Handler handler = new Handler();
    private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @SuppressLint("DefaultLocale")
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d(TAG,  " onReceive action = " + action);
            if (action == null) {
                return;
            }
            switch (action) {
                case BleCons.ACTION_BATTERY -> {
                    int vDeviceType = intent.getIntExtra("EXTRA_DEVICE_TYPE", SmartDevice.TYPE_UNKNOW);
                    if (vDeviceType == SmartDevice.TYPE_CADENCE) {
                        int vBattery = intent.getIntExtra("EXTRA_BATTERY", 0);
                        batteryView.setText(vBattery + Separators.PERCENT);
                    }
                }
                case BleCons.ACTION_DEVICE_INFORMATION -> {
                    int csc = intent.getIntExtra("EXTRA_CSC_FUTURE", 0);
                    Log.d(TAG, "ACTION_DEVICE_INFORMATION csc=" + csc);
                    String deviceName = CadenceStatusActivity.this.device.getName();
                    if (csc == 1) {
                        deviceCandence.setVisibility(View.GONE);
                    } else if (csc == 2 ) {
                        wheelSettingView.setVisibility(View.GONE);
                        deviceSpeed.setVisibility(View.GONE);
                    } else if (csc == 7) {
                        if (deviceName.startsWith("SPD")) {
                            device.setFlags(1);
                            deviceCandence.setVisibility(View.GONE);
                        } else if (deviceName.startsWith("CAD")) {
                            device.setFlags(2);
                            wheelSettingView.setVisibility(View.GONE);
                            deviceSpeed.setVisibility(View.GONE);
                        }
                    }
                    requestBattery();
                }
                case BleCons.ACTION_CADENCE_DATAS -> {
                    Log.d(TAG, "ACTION_CADENCE_DATAS not used...");
                }
                case BleCons.ACTION_PRESSURE_DATAS -> {
                    if (!pressureLayout.isShown()) {
                        pressureLayout.setVisibility(View.VISIBLE);
                    }
                    float floatExtra = intent.getFloatExtra(BleCons.EXTRA_PRESSURE, 0.0f);
                    float floatExtra2 = intent.getFloatExtra(BleCons.EXTRA_TEMPERATURE, 0.0f);
                    float floatExtra3 = intent.getFloatExtra(BleCons.EXTRA_ALTITUDE, 0.0f);
                    pressureView.setText(String.format("气压：%.2f hPa", floatExtra));
                    temperatureView.setText(String.format("温度：%.2f ℃", floatExtra2));
                    altitudeView.setText(String.format("海拔：%.2f m", floatExtra3));
                }
                default -> {
                }
            }
        }
    };

    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.activity_cadence_status);
        bindView(getWindow().getDecorView());
        setupActionBar(true);
        XZDeviceHelper.registerConnectionStateListener(this);
        registerReceiver();
        this.device = Device.getByAddress(getIntent().getStringExtra(BleCons.EXTRA_DEVICE_ADDRESS), App.getContext().getUserId());

        if (this.device != null) {
            String deviceName = this.device.getName();
            this.nameView.setText(deviceName);
            this.wheelSettingView.setOnClickListener(view -> showWheelSettingDialog());
            this.unbindBtn.setOnClickListener(view -> unBoundDeviceConfirm());
            Log.d(TAG, "onCreate: name=" + deviceName + ", flags=" + device.getFlags());
            int vFlag = device.getFlags();
            if (vFlag == 1) {
                deviceCandence.setVisibility(View.GONE);
            } else if (vFlag == 2 ) {
                wheelSettingView.setVisibility(View.GONE);
                deviceSpeed.setVisibility(View.GONE);
            } else if (vFlag == 7) {
                if (deviceName.startsWith("SPD")) {
                    device.setFlags(1);
                    deviceCandence.setVisibility(View.GONE);
                } else if (deviceName.startsWith("CAD")) {
                    device.setFlags(2);
                    wheelSettingView.setVisibility(View.GONE);
                    deviceSpeed.setVisibility(View.GONE);
                }
            }
        } else {
            finish();
        }
    }


    public void unBoundDeviceConfirm() {
        new BiciAlertDialogBuilder(this)
                .setTitle(R.string.st_forget_sensor)
                .setMessage(R.string.st_are_you_sure_unbind)
                .setPositiveButton(R.string.mine_profile_dialog_btn_unbind, (dialogInterface, i) -> {
                    if (device.getDeviceNumber() > 0) {
                        MyHttpClient.deleteDevice(device.getDeviceNumber());
                    }
                    Device.deleteAll(Device.class, "address = ? and userId = ?",
                            device.getAddress(), String.valueOf(App.getContext().getUserId()));
                    XZDeviceHelper.disconnect(device.getAddress());
                    DeviceContext.startAndRefreshAutoConnector();
                    finish();
                }).setNegativeButton(R.string.str_sync_cancel, (dialogInterface, i) -> {
                }).show().setCanceledOnTouchOutside(true);
    }

    @Override
    public void onResume() {
        super.onResume();
        this.handler.postDelayed(() -> {
            float wheelLen = RemoteSharedPreference.getInstance().getFloat(SPConstant.KEY_WHEEL_LENGTH, 2.171f);
            wheelLengthView.setText(((int) (wheelLen * 1000.0f)) + " mm");
        }, 200L);
        boolean isConnected = XZDeviceHelper.isConnected(this.device.getAddress()); //not to use SmartDevice.TYPE_CADENCE
        Log.d(TAG, "onResume... isConnected=" + isConnected);
        if (isConnected) {
            requestBattery();
        } else {
            XZDeviceHelper.connect(this.device);
        }
    }

    private void requestBattery() {
        Log.d(TAG, "requestBattery...");
        this.batteryView.postDelayed(() -> {
            Intent intent = new Intent(BleCons.ACTION_REQUEST_BATTERY);
            intent.putExtra(BleCons.EXTRA_DEVICE_TYPE, SmartDevice.TYPE_CADENCE);
            intent.putExtra(BleCons.EXTRA_DEVICE_ADDRESS, device.getAddress());
            sendOrderedBroadcast(intent, null);
        }, 1400L);
    }

    @Override
    public void onDestroy() {
        BroadcastReceiver broadcastReceiver = this.broadcastReceiver;
        if (broadcastReceiver != null) {
            unregisterReceiver(broadcastReceiver);
        }
        XZDeviceHelper.unregisterConnectionStateListener(this);
        super.onDestroy();
    }

    private void registerReceiver() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BleCons.ACTION_BATTERY);
        intentFilter.addAction(BleCons.ACTION_DEVICE_INFORMATION);
        intentFilter.addAction(BleCons.ACTION_CADENCE_DATAS);
        intentFilter.addAction(BleCons.ACTION_PRESSURE_DATAS);
        registerReceiver(this.broadcastReceiver, intentFilter, Context.RECEIVER_VISIBLE_TO_INSTANT_APPS);
    }

    public void showWheelSettingDialog() {
        new BiciAlertDialogBuilder(this).
                setItems(new String[]{getString(R.string.mine_wheel_setting_dialog_item_custom),
                        getString(R.string.mine_wheel_setting_dialog_item_check_table)}, (dialogInterface, i) -> {
                    Intent intent = new Intent(CadenceStatusActivity.this, WheelLengthSetting.class);
                    intent.putExtra("auto", i != 0);
                    startActivity(intent);
                }).show();
    }

    private void uploadDeivceInfo() {
        MyHttpClient.uploadDevice(new BiCiCallback() {
            @Override
            public void onResponseString(@NonNull String str) {
                try {
                    int i = new JSONObject(str).getInt("deviceServerId");
                    if (device != null) {
                        Device byAddress = Device.getByAddress(device.getAddress());
                        if (byAddress != null) {
                            byAddress.setDeviceNumber(i);
                            byAddress.save();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, this.device);
    }

    @Override
    protected void onRefreshUI(DisplayPoint displayPoint) {
        this.cadenceView.setText(String.valueOf(displayPoint.getCadence(0)));
        this.speedView.setText(this.decimalFormat.format(displayPoint.getSpeed(Utils.DOUBLE_EPSILON) * 3.6d));
    }

    private void bindView(View view) {
        this.speedView = view.findViewById(R.id.speedView);
        this.cadenceView = view.findViewById(R.id.cadenceView);
        this.nameView = view.findViewById(R.id.nameView);
        this.batteryView = view.findViewById(R.id.batteryView);
        this.wheelSettingView = view.findViewById(R.id.wheelSettingView);
        this.wheelLengthView = view.findViewById(R.id.wheelLengthView);
        this.unbindBtn = view.findViewById(R.id.unbindBtn);
        this.pressureLayout = view.findViewById(R.id.pressureLayout);
        this.pressureView = view.findViewById(R.id.pressureView);
        this.temperatureView = view.findViewById(R.id.temperatureView);
        this.altitudeView = view.findViewById(R.id.altitudeView);
        deviceCandence = view.findViewById(R.id.deviceCadenceView);
        deviceSpeed = view.findViewById(R.id.deviceSpeedView);
    }

    @Override
    public void onConnectionStateChanged(SmartDevice smartDevice, int newState, int errCode) {
        Log.d(TAG, "onConnectionStateChanged newState=" + newState);
        if (smartDevice.getAddress().equals(this.device.getAddress())) {
            if (newState == DeviceManager.STATE_CONNECTED) {
                requestBattery();
            } else if (newState == DeviceManager.STATE_DISCONNECTED) {
                finish();
            }
        }
    }
}
